home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 7
/
FM Towns Free Software Collection 7.iso
/
taropyon
/
zmodem
/
src
/
rsctrl.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-30
|
8KB
|
378 lines
/* :*****************************************************************
: "rsctrl.c" : RS-232C 制御
:*****************************************************************
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <dos.h>
#include <msdos.cf>
#include <setupif.h>
#define _RSCTRL_MAIN
#include "rsctrl.h"
#ifdef __HIGHC__
# pragma On(Align_labels);
#endif
#ifndef MALLOC
# define MALLOC malloc
#endif
#ifndef CALLOC
# define CALLOC calloc
#endif
#ifndef FREE
# define FREE free
#endif
int RS_reopen( int port, int md, int bp )
{
int er;
RSB_T *rsb = RsCtrl[port].rsb;
if ( rsb == NULL )
return (ERR);
RSB_DTR(port,1); /* DTR信号の保持 */
RSB_CLOSE(port);
#ifdef _RS_FMC
rsb->mode = md; /* 通信モード */
rsb->baud = bp; /* ボーレート */
// rsb->rbuf = 0;
// rsb->rbuf_seg = 0;
rsb->stime = 500; /* 送信タイムアウト */
rsb->rtime = 500; /* 受信タイムアウト */
rsb->rinfbuf = 0; /* 受信通知アドレス */
rsb->rinfbuf_seg = 0;
rsb->extmode = 0; /* 拡張モード */
// rsb->xon = 0; /* XONコード(0x11) */
// rsb->xoff = 0; /* XOFFコード(0x13) */
// rsb->obuf = 0;
// rsb->obuf_seg = 0;
#else
#ifdef _RS_N10
rsb->mode = md; /* 通信モード */
rsb->baud = bp; /* ボーレート */
rsb->stime = 0; /* 送信タイムアウト */
rsb->rtime = 0; /* 受信タイムアウト */
rsb->rinfbuf = 0; /* 受信通知アドレス */
rsb->extmode = 0; /* 拡張モード */
rsb->xon = 0; /* XONコード(0x11) */
rsb->xoff = 0; /* XOFFコード(0x13) */
#endif
#ifdef _RS_N11
rsb->mode = md & (~RSMD_EXINT); /* 通信モード */
rsb->baud = bp; /* ボーレート */
rsb->stime = 0; /* 送信タイムアウト */
rsb->rtime = 0; /* 受信タイムアウト */
rsb->rinfofs = 0; /* 受信通知アドレス */
rsb->rinfsel = 0; /* 受信通知セレクタ */
rsb->extmode = 0; /* 拡張モード */
rsb->xon = 0; /* XONコード(0x11) */
rsb->xoff = 0; /* XOFFコード(0x13) */
rsb->sendofs = 0; /* 送信バッファアドレス */
rsb->sendsel = 0; /* 送信バッファセレクタ */
#endif
#endif
RsCtrl[port].overFlag = 0;
#ifdef _RS_FMC
if ( (er = RSB_setpara(port, rsb)) == 0 )
#else
if ( (er = RSB_Setpara(port, (char *)rsb)) == 0 )
#endif
{
er = RSB_OPEN(port);
RSB_INITBUF( port );
}
return (er);
}
void RS_close(int port)
{
--RsCtrl[port].use;
if ( RsCtrl[port].use <= 0 )
{
RsCtrl[port].use = 0;
RSB_CLOSE( port );
}
}
static int RsbLimMax = (3*RS_BUFSIZ/4) & 0xFFFFFF00;
static int RsbLimMin = (1*RS_BUFSIZ/4) & 0xFFFFFF00;
RSB_T *RS_open( int port )
{
RSB_T *rsb;
RS_init();
if ( (rsb = RsCtrl[port].rsb) == NULL )
{
if ( (rsb = CALLOC(sizeof(RSB_T),1)) == NULL )
return (NULL);
RsCtrl[port].rsb = rsb;
}
#ifdef _RS_FMC
#if 0
{
RSB_PARA rsbPara;
_far void *ptr;
size_t bufsiz;
RSB_rdrpara(port, &rsbPara );
_FP_SEG(ptr) = rsbPara.rbuf_seg;
_FP_OFF(ptr) = rsbPara.rbuf;
bufsiz = *(_far unsigned int *)(ptr);
RsbLimMax = 3 * bufsiz / 4;
RsbLimMin = 1 * bufsiz / 4;
}
#else
RsbLimMax = 3 * 1024 / 4;
RsbLimMin = 1 * 1024 / 4;
#endif
if ( RsCtrl[port].use == 0 )
{
RSB_rdrpara(port, rsb );
RSB_setpara(port, rsb);
RSB_open(port);
RsCtrl[port].overFlag = 0;
}
#else
/* NATIVE RS */
{
RSBUF_T *rsBuf;
if ( (rsBuf = RsCtrl[port].rsBuf) == NULL )
{
if ( (rsBuf = CALLOC(sizeof(RSBUF_T),1)) == NULL )
return (NULL);
rsBuf->len = RS_BUFSIZ;
RsCtrl[port].rsBuf = rsBuf;
}
if ( RsCtrl[port].use == 0 )
{
static RSYSINF_T *rsys = NULL;
if ( rsys == NULL )
{
if ( (rsys = MALLOC(sizeof(RSYSINF_T))) == NULL )
return (NULL);
ESR_setupInfo(rsys);
}
rsb->baud = rsys->rs232c[port].baud;
rsb->mode = rsys->rs232c[port].mode; /* & (~RSMD_EXINT); */
rsb->rbuf = (char *)rsBuf; /* 受信バッファアドレス */
rsb->sel = getds(); /* セレクター値 */
#ifdef _RS_N11
RSB_Setpara(port, (char *)rsb);
#endif
RSB_OPEN(port);
RsCtrl[port].overFlag = 0;
}
}
#endif
++RsCtrl[port].use;
return (rsb);
}
int RS_chk(int port)
{
int len;
if ( RsCtrl[port].use == 0 )
return (ERR);
RSB_READ(port,&len);
if ( RsCtrl[port].overFlag == FALSE )
{
if ( len > RsbLimMax )
{ RsCtrl[port].overFlag = TRUE;
RSB_CTRL(port,0x02);
}
} else
{
if ( len < RsbLimMin )
{ RsCtrl[port].overFlag = FALSE;
RSB_CTRL(port,0x22);
}
}
return (len);
}
int RS_getc(int port)
{
UINT i;
UINT st;
int ch;
if ( RsCtrl[port].use == 0 )
return (ERR);
RETRY:
i = 0;
LOOP
{ if ( RSB_RECEIVE(port,&ch,&st) == 0 )
break;
if ( ++i > RS_TIMEOUT_LIMIT )
{ ch = 0;
break;
}
}
ch &= 0xFF;
#ifdef _BPLUS_
if ( ch == 0x05 && (RsCtrl[port].attr & RSATT_BP) )
{ BP_Term_ENQ(port);
goto RETRY;
} else if ( ch == 0x10 && (RsCtrl[port].attr & RSATT_BP) )
{ BP_DLE_Seen(port);
goto RETRY;
}
#endif
return (ch);
}
void RS_putc(int port, int ch)
{
UINT st;
if ( RsCtrl[port].use == 0 )
return;
#ifdef _RS_FMC
RSB_send(port,ch,&st);
#else
{
REG UINT i;
for ( i = 0 ; i < RS_TIMEOUT_LIMIT; ++i )
{ if ( RSB_Send(port,ch,&st) == 0 )
break;
}
}
#endif
}
void RS_puts( int port, CONST char *s )
{
while ( *s )
{
RS_putc( port, (*s) & 0xFF );
++s;
}
}
void RS_printf( int port, CONST char *form, ... )
{
va_list arg;
char tmp[BUFSIZ];
va_start( arg, form );
vsprintf( tmp, form, arg );
va_end(arg);
RS_puts( port, tmp );
}
void RS_breakOut( int port, int tm )
{
if ( RsCtrl[port].use == 0 )
return;
RSB_BREAK(port, tm );
}
static char rsInit = FALSE;
/*************************************************************************
* 一時停止処理(子プロセス呼び出しのため)
*-------------------------------------------------------------------------
* ※ この関数を使った後には,必ずRS_continue を実行すること
*************************************************************************/
void RS_pause(void)
{
int port;
if ( rsInit )
{
for ( port = 0; port < RS_PORTNUM; ++port )
{
if ( RsCtrl[port].use > 0 )
{
if ( RsCtrl[port].overFlag == FALSE )
{
RsCtrl[port].overFlag = TRUE;
RSB_CTRL(port,0x02);
}
RSB_DTR(port,1); /* DTR信号の保持 */
RSB_CLOSE(port);
}
}
#ifndef _RS_FMC
RSB_End();
#endif
}
}
/*************************************************************************
* 再開処理(子プロセス呼び出しのため)
*************************************************************************/
void RS_continue(void)
{
int port;
if ( rsInit )
{
#ifndef _RS_FMC
RSB_Init();
#endif
for ( port = 0; port < RS_PORTNUM; ++port )
{
if ( RsCtrl[port].use > 0 )
{
#ifdef _RS_FMC
RSB_setpara(port, RsCtrl[port].rsb );
#else
RSB_Setpara(port, (char *)RsCtrl[port].rsb );
#endif
RSB_OPEN(port);
}
}
}
}
int RS_init(void)
{
#ifdef _RS_FMC
return (0);
#else
if ( rsInit )
return (NORMAL);
else
{ rsInit = TRUE;
return RSB_Init();
}
#endif
}
int RS_end(void)
{
#ifdef _RS_FMC
return (0);
#else
if ( rsInit )
{
int port;
for ( port = 0; port < RS_PORTNUM; ++port )
{
while ( RsCtrl[port].use > 0 )
RS_close( port );
}
return RSB_End();
} else
return (NORMAL);
#endif
}